
// 当用let 解构或 match 匹配一个可变引用时，Rust 会自动将其转化为不可变引用。针对struct tuple
// 因此，如果我们需要在函数中修改可变引用的值，则需要使用借用规则来避免数据竞争。

#[derive(Clone,Copy)]
struct Point { x: i32, y: i32 }

fn main() {
    let c = 'Q';

    // 以下两种写法，意义相同
    let ref ref_c1 = c;
    let ref_c2 = &c;

    println!("*ref_c1 === *ref_c2: {}", *ref_c1== *ref_c2);

    let point = Point { x: 0, y: 0 };

    let _copy_of_x  = {
        let Point {x: ref ref_to_x,y: _} = point;
        // return a copy of x fields of point
        *ref_to_x; 
    };

    // A mutable copy of `point`, 等号是copy的意思，必须实现copy trait才可以用等号的方式来赋值
    let mut mutable_point = point;

    {
        // ref can be paired with mut to create a mutable reference
        let Point {x: ref mut mut_ref_to_x,y: _} = mutable_point;
        *mut_ref_to_x = 1;
    }

    println!("point is (x:{}, y:{})", point.x, point.y);
    println!("mutable_point is x:{}, y:{}", mutable_point.x, mutable_point.y);

    let mut mut_tuple = (Box::new(1), 2);
    
    {
        let (ref mut x, _) = mut_tuple;
        *x = Box::new(5);
    }

    println!("mut_tuple is {:?}", mut_tuple);

}